package com.g2room.search.life;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

import org.apache.log4j.Logger;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

public class EsClient {
	private Logger LOG = Logger.getLogger(EsClient.class);
//	private final static Log LOG= LogFactory.getLog(EsClient.class); 
	public static final String FIELD_ID = "id";
	// 设置client.transport.sniff为true来使客户端去嗅探整个集群的状态，把集群中其它机器的ip地址加到客户端中，
	private static Settings settings = null;
	// 创建私有对象
	private static TransportClient client;
	
	private String index = "sh";
	private String host = "127.0.0.1";
	private String port = "9001";
	private String clusterName = "life";
	// 分片数，默认为5
	private int numberOfShards = 5;
	// 副本数， 默认为1
	private int numberOfReplicas = 0;
	private boolean transportSniff = true;
	
	public String getIndex() {
		return index;
	}

	public void setIndex(String index) {
		this.index = index;
	}

	public EsClient() {
		init();
	}
	public EsClient(String host, String port, String clusterName, String index) {
		this.host = host;
		this.port = port;
		this.clusterName = clusterName;
		this.index = index;
		init();
	}
	
	public EsClient(String index) {
		this.setIndex(index);
		init();
	}
	
	private Settings getSettings() {
		if(null == settings) {
			settings = Settings.builder()
//			// 设置分片
//			.put("number_of_shards", numberOfShards)
			// 设置集群名称
			.put("cluster.name", clusterName)
			.put("client.transport.sniff", transportSniff)
//			// 设置副本数量
//			.put("number_of_replicas", numberOfReplicas)
			.build();
		}
		return settings;
	}
	
	/**
	 *初始化
	 * @return
	 */
	public void init() {
		if(null == client) {
			if(null == host) {
				LOG.error("es init error, host is null");
				return;
			}
			try {
				// https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/transport-client.html
				String[] hosts = host.split(",");
				String[] ports = port.split(",");
//				client = new PreBuiltTransportClient(getSettings());
				client = TransportClient.builder().settings(getSettings()).build();
				for(int i=0; i< hosts.length; i++) {
					client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(hosts[i]), Integer.valueOf(ports[i])));
				}
			} catch (UnknownHostException e) {
				LOG.error("init es err,message:{}", e);
			}
		}
	}
	
	/**
	 * 获取Es连接
	 * @return
	 */
	public Client getClient() {
		if(null == client) {
			init();
		}
		return client;
	}

	public void close() {
		if(null != client) client.close();
	}
	
	// 定义索引的映射类型
    public static PutMappingRequest defineMapping(String index, String type) {
    	PutMappingRequest pmr = null;
    	try {
    		XContentBuilder builder = XContentFactory.jsonBuilder();
    		builder.startObject()
            .startObject(type)
                .startObject("properties")
	                .startObject("id").field("type", "integer").field("store", "true").field("index","not_analyzed").endObject()
					.startObject("status").field("type", "integer").field("store", "true").field("index","not_analyzed").endObject()
					.startObject("type").field("type", "integer").field("store", "true").field("index","not_analyzed").endObject()
					.startObject("displayorder").field("type", "integer").field("store", "true").field("index","not_analyzed").endObject()
					.startObject("icon").field("type", "string").field("store", "true").field("index","not_analyzed").endObject()
					.startObject("name").field("type", "string").field("store", "true").field("analyzer","ik").field("index","analyzed").endObject()
                .endObject()
                .endObject()
            .endObject();
    		pmr = Requests.putMappingRequest(index).type(type).source(builder);
    		client.admin().indices().putMapping(pmr).actionGet();
        } catch (IOException e) {
           e.printStackTrace();
        }
        return pmr;
    }
    
    public static void initMapping(String index, String type) {
    	EsClient ec = new  EsClient();
    	ec.init();
    	
		try {
			XContentBuilder mapping = getMapping(type);
			PutMappingRequest mappingRequest = Requests.putMappingRequest(index).type(type).source(mapping);
			client.admin().indices().putMapping(mappingRequest).actionGet();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
    
    public static void initMappingByCreate(String index, String type) {
    	EsClient ec = new  EsClient();
    	ec.init();
   	 	CreateIndexRequestBuilder cib = client.admin().indices().prepareCreate(index);
		try {
			XContentBuilder mapping = getMapping(type);
			cib.addMapping(type, mapping);
			cib.execute().actionGet();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
    
    /**
     * 获取Mapping
     * @param type
     * @return
     * @throws IOException 
     */
    private static XContentBuilder getMapping(String type) throws IOException {
    	XContentBuilder mapping = XContentFactory.jsonBuilder()
		.startObject()
		.startObject(type).startObject("properties").
				startObject("id").field("type", "string").endObject().
				startObject("icon").field("type", "string").field("index","not_analyzed").endObject().
				startObject("displayorder").field("type", "integer").endObject().
				startObject("type").field("type", "string").field("index","not_analyzed").endObject().
				startObject("status").field("type", "string").field("index","not_analyzed").endObject().
				startObject("url").field("type", "string").field("index","not_analyzed").endObject().
				startObject("name").field("type", "string").field("index","not_analyzed").endObject().
				endObject().endObject()
//			.startObject(type)
//				.startObject("properties")
//					.startObject("id").field("type", "integer").field("store", "true").field("index","not_analyzed").endObject()
//					.startObject("status").field("type", "integer").field("store", "true").field("index","not_analyzed").endObject()
//					.startObject("type").field("type", "integer").field("store", "true").field("index","not_analyzed").endObject()
//					.startObject("displayorder").field("type", "integer").field("store", "true").field("index","not_analyzed").endObject()
//					.startObject("icon").field("type", "string").field("store", "true").field("index","not_analyzed").endObject()
//					.startObject("name").field("type", "string").field("store", "true").field("analyzer","ik").field("index","not_analyzed").endObject()
//				.endObject()
//			.endObject()
		.endObject();
    	return mapping;
    }
	
    public static String getRouting(String type) {
    	return FIELD_ID;
    }
}
